<?php

declare(strict_types=1);

namespace App\CustHub\Service;

use App\Common\Service\Affiliate\JdService;
use App\Common\Service\Affiliate\WphService;
use App\CustHub\Constants\AffiliateAccountTypeConstants;
use App\CustHub\Mapper\ChAffiliateAccountMapper;
use App\CustHub\Mapper\ChAffiliatePidMapper;
use App\CustHub\Model\ChAffiliateAccount;
use Hyperf\Di\Annotation\Inject;
use Mine\Abstracts\AbstractService;
use Mine\Annotation\Transaction;
use Mine\Exception\NormalStatusException;
use function Hyperf\Collection\collect;
use function Hyperf\Collection\data_get;

class AffiliateAccountService extends AbstractService
{

    public $mapper;

    #[Inject]
    protected JdService $jdService;

    #[Inject]
    protected WphService $wphService;

    #[Inject]
    protected ChAffiliatePidMapper $pidMapper;

    public function __construct(ChAffiliateAccountMapper $mapper)
    {
        $this->mapper = $mapper;
    }


    public function getAccountList(array $params)
    {
        $type = $params['type'] ?? '';
        $p = ChAffiliateAccount::query()
            ->selectRaw('id,name,member_id,created_at,expire_time')
            ->where('main_uid',$params['main_uid'])
            ->when($type,function ($query) use ($type){
                $query->where('type',$type);
            })
            ->orderBy('created_at', 'desc')
            ->paginate($params['page_size']);

        $p->getCollection()->transform(function ($item){
            $item->is_exipred = $item->expire_time < time() ? 1 : 0;
            return $item;
        });

        return $this->mapper->setPaginate($p);
    }

    /**
     * 淘宝授权回调
     * @param array $data
     * @return bool|string
     */
    public function tbOauthCallback(array $data): bool|string
    {

        if(empty($data['access_token'])){
            return false;
        }
        $suc_jump      = 'http://' . urldecode($data['suc_jump']);

        $data['name']    = urldecode($data['taobao_user_nick']);

        $info = $this->mapper->findByMainUidAndMemberIdAndType($data['main_uid'],$data['taobao_user_id'],AffiliateAccountTypeConstants::TAOBAO);

        $data['member_id'] = $data['taobao_user_id'];
        $data['type'] = AffiliateAccountTypeConstants::TAOBAO;
        $data['code'] = AffiliateAccountTypeConstants::getCode($data['type']);
        $data['auth_time'] = time();
        $data['expire_time'] = time() + $data['expires_in'] ?? 90 * 3600 * 24;
        if(empty($info)){
            $id = $this->mapper->save($data);
            if(!$id){
                return false;
            }
        }else{
            $id = $info['id'];
            $rst = $this->mapper->update($info['id'],$data);
            if(!$rst){
                return false;
            }
        }

        $this->mapper->rmCache($id);
        return $this->getHtml($suc_jump);
    }

    /**
     * 京东授权回调
     * @param array $data
     * @return bool|string
     */
    public function jdOauthCallback(array $data): bool|string
    {
        $state = data_get($data,'state');
        $state = base64_decode($state);
        $param = json_decode($state ,true);
        if(empty($state)){
            return false;
        }
        $suc_jump      = 'http://' . urldecode($data['suc_jump']);

        if(isset($param['access_token'])){
            $memberId = $param['xid'];
            $info = $this->mapper->findByMainUidAndMemberIdAndType($data['main_uid'],$memberId,AffiliateAccountTypeConstants::JD);

            $data['member_id'] = $memberId;
            $data['access_token'] = $param['access_token'];
            $data['refresh_token'] = $param['refresh_token'];
            $data['type'] = AffiliateAccountTypeConstants::JD;
            $data['code'] = AffiliateAccountTypeConstants::getCode($data['type']);
            $data['auth_time'] = time();
            $data['expire_time'] = time() + $param['expires_in'] ?? 90 * 3600 * 24;

            if(empty($info)){
                $data['name'] = '京东';
                $id = $this->mapper->save($data);
                if(!$id){
                    return false;
                }
            }else{
                $id = $info['id'];
                $rst = $this->mapper->update($info['id'],$data);
                if(!$rst){
                    return false;
                }
            }

            $this->mapper->rmCache($id);
            return $this->getHtml($suc_jump);
        }
        return false;
    }


    /**
     * 淘宝授权回调
     * @param array $data
     * @return bool|string
     */
    public function pddOauthCallback(array $data): bool|string
    {
        if(empty($data['access_token'])){
            return false;
        }
        $suc_jump      = 'http://' . urldecode($data['suc_jump']);

        $data['name']    = urldecode($data['owner_name']);

        $info = $this->mapper->findByMainUidAndMemberIdAndType($data['main_uid'],$data['owner_id'],AffiliateAccountTypeConstants::PDD);

        $data['member_id'] = $data['owner_id'];
        $data['type'] = AffiliateAccountTypeConstants::PDD;
        $data['code'] = AffiliateAccountTypeConstants::getCode($data['type']);
        $data['auth_time'] = time();
        $data['expire_time'] = time() + $data['expires_in'] ?? 90 * 3600 * 24;
        if(empty($info)){
            $id = $this->mapper->save($data);
            if(!$id){
                return false;
            }
        }else{
            $id = $info['id'];
            $rst = $this->mapper->update($info['id'],$data);
            if(!$rst){
                return false;
            }
        }

        $this->mapper->rmCache($id);
        return $this->getHtml($suc_jump);
    }

    /**
     * 唯品会授权回调
     * @param array $data
     * @return bool|string
     */
    public function wphOauthCallback(array $data): bool|string
    {

        $code = data_get($data,'code');
        if(empty($code)){
            return false;
        }
        $suc_jump      = 'http://' . urldecode($data['suc_jump']);

        $result = $this->wphService->getAccessToken($code);
        if($result && isset($result['access_token'])){
            $memberId = $result['open_id'];
            $info = $this->mapper->findByMainUidAndMemberIdAndType($data['main_uid'],$memberId,AffiliateAccountTypeConstants::WPH);

            $data['member_id'] = $memberId;
            $data['access_token'] = $result['access_token'];
            $data['refresh_token'] = $result['refresh_token'];
            $data['type'] = AffiliateAccountTypeConstants::WPH;
            $data['code'] = AffiliateAccountTypeConstants::getCode($data['type']);
            $data['auth_time'] = time();
            $data['expire_time'] = time() + $result['expires_in'] ?? 90 * 3600 * 24;

            if(empty($info)){
                $data['name'] = '唯品会';
                $id = $this->mapper->save($data);
                if(!$id){
                    return false;
                }
            }else{
                $id = $info['id'];
                $rst = $this->mapper->update($info['id'],$data);
                if(!$rst){
                    return false;
                }
            }

            $this->mapper->rmCache($id);
            return $this->getHtml($suc_jump);
        }
        return false;
    }

    private function getHtml($jumpUrl)
    {
        $html = <<<HTML
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>结果</title>
    <style type="text/css">
        .box{
            display: flex;
            width: 100%;
            height: 100%;
            flex-direction: row;  
            justify-content: center; 
            align-items: center; 
            position: fixed;
        }
        .cont{
            width: 30%;
            height: 100px;
            text-align: center;
            flex-grow:1;
        }
    </style>
</head>
<body>
    <div class="box">
        <div class="cont">
            <h2>授权成功，<span class="clock" id="clock">3</span>秒后将自动跳转</h2>
        </div>
    </div>
    <script>
        var timeClock;
        function sendCode() {
            var timer_num = 3;
            timeClock=setInterval(function(){
                timer_num--;
                document.getElementById('clock').innerHTML=timer_num

                if (timer_num == 0) {
                    clearInterval(timeClock);
                    top.location.href="{$jumpUrl}";
                }
            },1000)
        }
        sendCode()
    </script>
</body>
</html>
HTML;
        return $html;
    }

    /**
     * 保存无需授权的联盟账号信息
     * @param array $data
     * @return mixed
     */
    public function save(array $data): mixed
    {
        $type = $data['type'];

        $typeArr = [
            AffiliateAccountTypeConstants::ELE,
            AffiliateAccountTypeConstants::MT
        ];

        if(!in_array($type,$typeArr)){
            throw new NormalStatusException("当前暂不支持该类型授权");
        }

        $info = $this->mapper->findByMainUidAndMemberIdAndType($data['main_uid'],$data['member_id'],AffiliateAccountTypeConstants::WPH);
        $data['expire_time'] = strtotime($data['expire_time']);
        $data['auth_time'] = time();
        $data['code'] = AffiliateAccountTypeConstants::getCode((int)$data['type']);
        if(!empty($info)){
            $this->mapper->rmCache($info['id']);
            return $this->mapper->update($info['id'],$data);
        }else{
            return $this->mapper->save($data);
        }
    }

    #[Transaction]
    public function deleteAccount(array $params): bool
    {
        $id = $params['id'];

        $this->mapper->delete([$id]);

        $this->mapper->rmCache($id);
        $pidList = $this->pidMapper->findByAffiliateAccountId($id);

        foreach ($pidList as $pid){
            $pid->delete();
            $this->pidMapper->rmCache($pid->id);
        }
        return true;
    }
}